/**
 * @Author:       lee
 * @Email:        liwei@hiynn.com
 * @DateTime:     2017-11-11 09:37:54
 * @Description:  再次学习红宝书第六章《面向对象的程序设计》
 */
/**
 *  数据属性：
 *  [[Configurable]]:能否通过delete删除属性
 *  [[Enumerable]]:能否通过for-in循环返回属性
 *  [[Writable]]:能否修改属性的值
 *  [[Value]]：包含这个属性的数据值
 */
var person = {}
Object.defineProperty(person, 'hobby', {
  writable: false,
  value: 'code'
})
console.log(person.hobby) // code
person.hobby = 'book'
console.log(person.hobby) // code
  /**
   * 访问器属性：
   * 只指定getter，表示属性不能写
   */
var person = {
  age: 25
}
Object.defineProperty(person, 'age', {
  get: function() {
    return 'funlee'
  }
})
var test = person.age // funlee
console.log(test)
  /**
   * getOwnPropertyDescriptor
   */
var person = {}
Object.defineProperties(person, {
  age: {
    value: 25
  },
  job: {
    value: 'web'
  }
})
var description = Object.getOwnPropertyDescriptor(person, 'job')
console.log(description.value)
console.log(description.configurable)
  /**
   * 工厂模式
   */
function createPerson(name, age, job) {
  var o = new Object()
  o.name = name;
  o.age = age;
  o.job = job;
  o.syaName = function() {
    console.log(this.name)
  }
  return o;
}
/**
 * 构造函数模式
 */
function createPerson(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.syaName = function() {
    console.log(this.name)
  }
}
/**
 * 把函数定义转移到构造函数外部
 * 依然不够好
 */
function createPerson(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.syaName = sayName
}

function sayName() {
  console.log(this.name)
}
/**
 * 原型模式来解决上述问题
 */
function createPerson() {}
createPerson.prototype.sayName = function() {
  console.log(this.name)
}